package com.yuntsg.nnsfcp.service.back.reporthandle;


import com.alibaba.fastjson.JSON;
import com.aspose.words.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yuntsg.nnsfcp.common.utils.CheckUtil;
import com.yuntsg.nnsfcp.front.entity.OrderBaseInfo;
import com.yuntsg.nnsfcp.front.entity.Wosdetail;
import com.yuntsg.nnsfcp.front.mapper.OrderBaseInfoMapper;
import com.yuntsg.nnsfcp.front.mapper.WosdetailMapper;
import com.yuntsg.nnsfcp.service.front.OrderService;
import com.yuntsg.nnsfcp.service.front.pojo.WebOfScienceShowListEntity;
import com.yuntsg.nnsfcp.service.front.ut.DateUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import static java.util.regex.Pattern.compile;

/**
 * cnki的报告处理
 *
 * @author ：ljx
 * @date ：Created in 2019/12/22  10:57
 */
@Component
public class CnkiReportService {

    @Value("${myproperties.uploadPath}")
    private String upload;


    @Resource
    private OrderBaseInfoMapper orderBaseInfoMapper;

    @Resource
    private WosdetailMapper wosdetailMapper;

    @Resource
    private OrderService orderService;

    @Resource
    private HttpServletRequest request;


    /**
     * 这个方法处理 情报所大学人才引进模板-T.docx
     *
     * @param applyId 订单流水号
     * @return 情报所大学人才引进模板-T.docx 报告生成路径
     */
    public String renCai(String applyId, String citedSelect) throws Exception {
        OrderBaseInfo order = orderBaseInfoMapper.selectOne(new QueryWrapper<OrderBaseInfo>().eq("apply_id", applyId));
        CheckUtil.notNull(order, "未找到订单");

        Integer type = order.getType();
        CheckUtil.check(type == 2, "只支持查引模式");

        // 不是选中人才引用模板的不能使用.
        // 4 == 人才引用模板.
        if (!"4".equals(citedSelect)) {
            return null;
        }

        List<Wosdetail> wosdetailList = wosdetailMapper.selectList(new QueryWrapper<Wosdetail>().eq("commissionid", applyId));
        CheckUtil.check(wosdetailList != null && wosdetailList.size() > 0, "未找到文章");

        // 报告模板的输入流
        InputStream templateInput = getTemplate();
        CheckUtil.notNull(templateInput, "模板丢失_2");

        // 得到 word 报告模板文档.
        Document document = new Document(templateInput);
        // 获取范围m
        Range range = document.getRange();

        // 初始化页面属性
        range.replace(compile("\\{\\{wtr}}"), order.getWtrName());
        range.replace(compile("\\{\\{au}}"), "第一/通讯作者");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        String year = sdf.format(new Date());
        range.replace(compile("\\{\\{report-year}}"), year);
        range.replace(compile("\\{\\{wos-size}}"), String.valueOf(wosdetailList.size()));

        // 用户选择的被引计算方式
        String citationStatus = order.getCitationStatus();
        //作者的三种排除方式
        if ("1".equals(citationStatus)) {
            range.replace(compile("\\{\\{pc-au}}"), "排除作者本人");
        }
        if ("2".equals(citationStatus)) {
            range.replace(compile("\\{\\{pc-au}}"), "排除所有作者");
        }
        if ("3".equals(citationStatus)) {
            range.replace(compile("\\{\\{pc-au}}"), "排除项目合作者");
        }

        // 用户统计wos被引次数的和
        int wosSum = 0;
        // 得到文章总的表格
        Table table = (Table) document.getChild(NodeType.TABLE, 0, true);

        for (int i = 0; i < wosdetailList.size(); i++) {
            // 备份克隆最后一行
            Node deepClone = table.getLastRow().deepClone(true);

            Wosdetail wosdetail = wosdetailList.get(i);
            String detailList = wosdetail.getDetailList();
            WebOfScienceShowListEntity detailPage = JSON.parseObject(detailList, WebOfScienceShowListEntity.class);
            if (detailPage == null) {
                continue;
            }

            // 拿到最后一行, 开始替换
            Row row = table.getLastRow();
            Range tableRange = row.getRange();

            // 汇总统计 wos 的被引次数(求和)
            Integer citedNum = wosdetail.getWosHeCitedNum();
            if (citedNum != null) {
                if (citedNum > 0) {
                    wosSum += citedNum;
                }
            }

            // set行的内容
            setRow(detailPage, wosdetail, i, tableRange);

            // 向后追加备份克隆 (用于给下一个文章备份)
            if ((i + 1) < wosdetailList.size()) {
                table.getRows().add(deepClone);
            }
        }

        // 总被引次数
        range.replace(compile("\\{\\{wos-sum}}"), wosSum + "");


        String savePath = request.getServletContext().getRealPath(upload + DateUtil.getCurrentYmdStr());
        File file = new File(savePath);
        if (!file.exists()) {
            boolean mkdirs = file.mkdirs();
        }

        String projectNo = order.getProjectNo();
        String wtrName = order.getWtrName();
        String fileName = wtrName + "-" + projectNo;

        savePath = getPath(fileName, ".docx");
        document.save(savePath, SaveFormat.DOCX);

        savePath = getPath(fileName, ".pdf");
        document.save(savePath, SaveFormat.PDF);

        // 返回存储文件的路径.
        return upload + DateUtil.getCurrentYmdStr() + "/" + fileName + ".docx";
    }

    /**
     * 项目相对路径 + 文件保存路径
     *
     * @param suffix   提供文件后缀
     * @param fileName 文件名
     * @return
     */
    private String getPath(String fileName, String suffix) {
        fileName = fileName + suffix;
        String returnPath = upload + DateUtil.getCurrentYmdStr() + "/" + fileName;
        return request.getServletContext().getRealPath(returnPath);
    }

    /**
     * 铺设 行的内容
     *
     * @param detailPage 文章页详情
     * @param wosdetail  本地文章数据
     * @param i          用于模板中的序号
     * @param range      行对象
     * @throws Exception
     */
    private void setRow(WebOfScienceShowListEntity detailPage, Wosdetail wosdetail, int i, Range range) throws Exception {
        // 序号
        range.replace(compile("xh"), String.valueOf(i + 1));
        // 封装好的文章信息.
        String titleBuilder = getTitleBuilder(detailPage, wosdetail);
        range.replace(compile("ti"), titleBuilder);

        // 作者顺序
        String auOrder = wosdetail.getSearchuse();
        range.replace(compile("au"), auOrder);

        String yinZi = wosdetail.getYinzi1();
        if (StringUtils.isNotEmpty(yinZi)) {
            range.replace(compile("yz"), yinZi);
        } else {
            range.replace(compile("yz"), "--");
        }

        String zky = wosdetail.getZky();
        if (StringUtils.isNotEmpty(zky)) {
            range.replace(compile("qk"), zky);
        } else {
            range.replace(compile("qk"), "--");
        }

        // wos 总被引次数
        Integer wosHeCitedNum = wosdetail.getWosHeCitedNum();
        if (wosHeCitedNum != null) {
            range.replace(compile("wos-he"), String.valueOf(wosHeCitedNum));
        } else {
            range.replace(compile("wos-he"), "0");
        }

        // 备注选项
        String otherBuilder = getOtherBuilder(wosdetail);
        range.replace(compile("bz"), otherBuilder);
    }

    /**
     * 报告模板中  备注列的数据封装
     *
     * @param wosdetail
     * @return
     */
    private String getOtherBuilder(Wosdetail wosdetail) {
        StringBuilder sb = new StringBuilder();
        String esiHc = wosdetail.getEsiHc();
        if (StringUtils.isNotEmpty(esiHc)) {
            sb.append(esiHc);
        }
        String esiHp = wosdetail.getEsiHp();
        if (StringUtils.isNotEmpty(esiHp)) {
            if (StringUtils.isNotEmpty(sb.toString())) {
                sb.append(ControlChar.LINE_BREAK);
            }
            sb.append(esiHp);
        }
        String top = wosdetail.getTop();
        if (StringUtils.isNotEmpty(top)) {
            if (StringUtils.isNotEmpty(sb.toString())) {
                sb.append(ControlChar.LINE_BREAK);
            }
            if ("1".equals(top)) {
                sb.append("TOP期刊");
            }
        }
        String schoolSupplemented = wosdetail.getSchoolSupplemented();
        if (StringUtils.isNotEmpty(schoolSupplemented)) {
            if (StringUtils.isNotEmpty(sb.toString())) {
                sb.append(ControlChar.LINE_BREAK);
            }
            sb.append("权威期刊");
        }
        return sb.toString();
    }

    /**
     * 封装报告中的 "文章信息" 一栏
     *
     * @param detailPage
     * @param wosdetail
     * @return
     */
    private String getTitleBuilder(WebOfScienceShowListEntity detailPage, Wosdetail wosdetail) {
        StringBuilder sb = new StringBuilder();
        String title = detailPage.getTitle();
        if (StringUtils.isNotEmpty(title)) {
            sb.append("标题:").append(title);
        }
        String author = detailPage.getAuthor();
        if (StringUtils.isNotEmpty(author)) {
            sb.append(ControlChar.LINE_BREAK).append("作者:").append(author);
        }
        String source = detailPage.getSource();
        if (StringUtils.isNotEmpty(source)) {
            sb.append(ControlChar.LINE_BREAK).append("来源出版物:").append(source).append(ControlChar.LINE_BREAK);
        }
        String juan = detailPage.getJuan();
        if (StringUtils.isNotEmpty(juan)) {
            sb.append("卷:").append(juan);
        }
        String qi = detailPage.getQi();
        if (StringUtils.isNotEmpty(qi)) {
            boolean boo = compile("卷:").matcher(sb.toString()).find();
            if (boo) {
                sb.append(" ");
            }
            sb.append("期:").append(qi);
        }
        String ye = detailPage.getYe();
        if (StringUtils.isNotEmpty(ye)) {
            boolean boo = compile("卷:").matcher(sb.toString()).find();
            boolean boo1 = compile("期:").matcher(sb.toString()).find();
            if (boo || boo1) {
                sb.append(" ");
            }
            sb.append("页:").append(ye);
        }
        String nian = detailPage.getNian();
        if (StringUtils.isNotEmpty(nian)) {
            sb.append(ControlChar.LINE_BREAK).append("出版年:").append(nian);
        }
        String doi = detailPage.getDoi();
        if (StringUtils.isNotEmpty(doi)) {
            sb.append(ControlChar.LINE_BREAK).append("DOI:").append(doi);
        }
        String citedNum = wosdetail.getCitedNum();
        if (StringUtils.isNotEmpty(citedNum)) {
            sb.append(ControlChar.LINE_BREAK).append("Web of Science 核心合集中的 \"被引频次\":").append(citedNum);
        }
        String ut = detailPage.getUt();
        if (StringUtils.isNotEmpty(ut)) {
            sb.append(ControlChar.LINE_BREAK).append("入藏号:").append(ut);
        }
        String literatureType = detailPage.getLiteratureType();
        if (StringUtils.isNotEmpty(literatureType)) {
            sb.append(ControlChar.LINE_BREAK).append("文献类型:").append(literatureType);
        }
        String issn = detailPage.getIssn();
        if (StringUtils.isNotEmpty(issn)) {
            sb.append(ControlChar.LINE_BREAK).append("ISSN:").append(issn);
        }
        return sb.toString();
    }

    /**
     * 获取模板
     *
     * @return
     */
    private InputStream getTemplate() {
        try {
            File file = ResourceUtils.getFile("classpath:templates/情报所大学人才引进模板-T.docx");
            if (file.exists()) {
                return FileUtils.openInputStream(file);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}
